package com.example.web.service.server.springbootwebserviceserver.controller;

import cn.hutool.core.lang.Console;
import cn.hutool.core.util.XmlUtil;
import cn.hutool.http.webservice.SoapClient;
import cn.hutool.json.JSONUtil;
import com.example.web.service.server.springbootwebserviceserver.server.dto.TestBean;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import java.util.Objects;

/**
 * MockController.
 *
 * @author <a href='mailto:likeguo@apache.com'> likeguo </a>
 */
@RestController
@RequestMapping("mock")
public class MockController {
    
    @GetMapping
    public String mock() {
        try {
            // 创建动态客户端
            JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
            
            Client client = dcf.createClient("http://localhost:8080/soap/ws/api?wsdl");
            ObjectMapper mapper = new ObjectMapper();
            Object[] objects = client.invoke("getTest");
            System.out.println("返回数据:" + mapper.writeValueAsString(objects));
            return mapper.writeValueAsString(objects);
        } catch (java.lang.Exception e) {
            e.printStackTrace();
            return "error:" + e.getMessage();
        }
    }
    
    @GetMapping("/2")
    public String mock2(TestBean bean) {
        
        try {
            // 创建动态客户端
            JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
            
            Client client = dcf.createClient("http://localhost:8080/soap/ws/api?wsdl");
            ObjectMapper mapper = new ObjectMapper();
            QName qName = new QName("http://server.springbootwebserviceserver.server.service.web.example.com/", "getTest2");
            Object[] objects = client.invoke(qName, JSONUtil.toJsonStr(bean));
            System.out.println("返回数据:" + mapper.writeValueAsString(objects));
            return mapper.writeValueAsString(objects);
        } catch (java.lang.Exception e) {
            e.printStackTrace();
            return "error:" + e.getMessage();
        }
    }
    
    @GetMapping("/3")
    public String mock3(TestBean bean) {
        
        try {
            // 创建动态客户端 wsimport -p cn.hcx.mobile -s http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl
            JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
            
            Client client = dcf.createClient("http://localhost:8080/soap/ws/api?wsdl");
            ObjectMapper mapper = new ObjectMapper();
            Object[] objects = client.invoke("getTest3", bean.getName());
            System.out.println("返回数据:" + mapper.writeValueAsString(objects));
            return mapper.writeValueAsString(objects);
        } catch (java.lang.Exception e) {
            e.printStackTrace();
            return "error:" + e.getMessage();
        }
    }
    
    @GetMapping("/4")
    public String mock4(TestBean bean) {
        try {
            // 新建客户端
            SoapClient client = SoapClient.create("http://localhost:8080/soap/ws/api?wsdl")
                    // 设置要请求的方法，此接口方法前缀为web，传入对应的命名空间
                    .setMethod("web:getTest2", "http://server.springbootwebserviceserver.server.service.web.example.com/");
//                    // 设置参数，此处自动添加方法的前缀：web
//                    .setParam("test2", XmlUtil.toStr(XmlUtil.beanToXml(bean)));
//
            final SOAPElement test2 = client.getMethodEle().addChildElement("test2","web");
            test2.addChildElement("id").setValue(Objects.toString(bean.getId()));
            test2.addChildElement("name").setValue(Objects.toString(bean.getName()));
            test2.addChildElement("desc").setValue(Objects.toString(bean.getDesc()));
            // 发送请求，参数true表示返回一个格式化后的XML内容
            Console.log("send:");
            Console.log(client.getMsgStr(true));
            // 返回内容为XML字符串，可以配合XmlUtil解析这个响应
            final String send = client.send(false);
            Console.log("return:");
            final Document document = XmlUtil.parseXml(send);
            Console.log(XmlUtil.format(document));
            final Node returnNode = find(document, "return");
            final String res = JSONUtil.toJsonStr(XmlUtil.xmlToMap(returnNode));
            Console.log(res);
            return res;
        } catch (java.lang.Exception e) {
            e.printStackTrace();
            return "error:" + e.getMessage();
        }
    }
    
    private Node find(Node node, String name) {
        if (Objects.equals(node.getNodeName(), name)) {
            return node;
        }
        final NodeList childNodes = node.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            final Node item = childNodes.item(i);
            if (item.hasChildNodes()) {
                return find(node.getFirstChild(), name);
            }
        }
        return null;
    }
}
